#pragma once

#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h> 
#include <pthread.h>


#include "log.hpp"
#include "Task.hpp"
#include "ThreadPool.hpp"


namespace Server
{
    // using namespace std;

    static const uint16_t gport = 8080;
    static const int gbacklog = 5;


    class tcpServer
    {
    public:
        tcpServer(const uint16_t& port = gport)
            :_listensock(-1),_port(port)
        {}
        void initServer()
        {
            //1.创建socket文件套接字对象
            _listensock = socket(AF_INET,SOCK_STREAM,0);
            if(_listensock < 0)
            {
                logMessage(FATAL,"create socket error");
                exit(SOCKET_ERR);
            }
            logMessage(NORMAL,"create socket success: %d",_listensock);

            // 2.bind 绑定自己的网络信息
            struct sockaddr_in local;
            memset(&local,0,sizeof(local));
            local.sin_family = AF_INET;
            local.sin_port = htons(_port);
            local.sin_addr.s_addr = INADDR_ANY;
            if(bind(_listensock,(struct sockaddr*)&local,sizeof(local)) < 0)
            {
                logMessage(FATAL,"bind socket error");
                exit(BIND_ERR);
            }
            logMessage(NORMAL,"bind socket success");

            //3. 设置socket为监听状态
            if(listen(_listensock,gbacklog) < 0)
            {
                logMessage(FATAL,"listen socket error");
                exit(LISTEN_ERR);
            }
            logMessage(NORMAL,"listen socket success");


        }
        void start()
        {
            ThreadPool<Task>::GetInstance()->run();

            for( ; ; )  //死循环
            {
                //4. Server获取新链接
                //sock 是用于和client进行通信的
                struct sockaddr_in peer;
                socklen_t peer_len = sizeof(peer);
                int sock = accept(_listensock,(struct sockaddr*)&peer,&peer_len);
                if(sock < 0)
                {
                    logMessage(ERROR,"accept error,next");
                    continue;
                }
                logMessage(NORMAL,"accept a new link success sock:%d",sock);
            
                //5. 未来通信就用这个sock，面向字节流的，后面全是文件操作
                
                ThreadPool<Task>::GetInstance()->push(Task(sock, serviceIO));

            }
        }
       
         
        ~tcpServer()
        {}
    private:
        int _listensock;    //不是用来数据通信的，它是监听链接是否到来的，用于获取新链接的
        uint16_t _port;
    } ;
    
}//namespace end Server 
